`uvm_do sequence macros - mahadevaswamy05/github_experiments GitHub Wiki

'uvm_do sequence macros

How to use 'uvm_do sequence macros
we saw that a sequence calls on the tasks using start_item() and finish_item(). you can avoid putting all these statements in your code by simply calling the UVM Sequence macros that are uvm_do or uvm_do_with. and At the completion time, these macros will be substituted with calls to start_item() and finish_item()

There are primarily 7 types of UVM macros that can be executed in the default sequencer.

  1. `uvm_do
  2. `uvm_do_with
  3. `uvm_do_pri
  4. `uvm_do_pri_with
  5. `uvm_do_on
  6. `uvm_do_on_pri
  7. `uvm_do_on_with
  8. `uvm_do_on_pri_with
  • `uvm_do: Execute this sequence on the default sequencer with the item provided.

macros will identify if the argument provided is a sequence item and will call start() or start_item() accordingly.

  • `uvm_do_with: override any default constraints with inline values.

  • `uvm_do_pri: Execute based on the priority value, used when running multiple sequences simultaneously.

  • `uvm_do_pri_with: Execute based on priority and override default constraints with inline values.

diagram

Untitled Diagram drawio (17)

  Figure. The above figure shows the 'uvm_do sequence macros 
  • Example

     class sequence1 extends uvm_sequence#(transaction);
      `uvm_object_utils(sequence1)
    
      function new(input string name="sequence1");
      super.new(name);
      endfunction
    
    
     virtual task pre_body();
    
     `uvm_info("SEQ1","Pre-Body",UVM_MEDIUM)
      endtask
    
      virtual task body();
      `uvm_info("SEQ1","Body",UVM_MEDIUM)
      repeat(1) begin
      `uvm_do(req)
      req.print();
      `uvm_do_with(req,{a==4;b==6;})
      req.print();
      `uvm_do_pri(req,5)
      req.print(uvm_default_table_printer);
      end
    endtask
    
    virtual task post_body();
      `uvm_info("SEQ1","Post-Body",UVM_MEDIUM)
    endtask
    
     endclass  
    
    
         Example.1 - uvm_do macros
    

In the above example, Here we were trying the uvm_do sequence macros method. In that code, we used only uvm_do and uvm_do_with methods. then more code explanations just refer the example 1. (starting code). while using the uvm_do method we can't customize the code things. this is the main drawback of the uvm_do macros. and **uvm_do_with ** this work like an inline constraint method.

GitHub lab code link :

GitHub log code link :

  • output snap Untitled Diagram drawio (19)

         output.1 - output for uvm_do macros 
    

In the above output, we were using uvm_do macros to generate the sequence. And in that output first tree output is uvm_do which prints some random values and the second tree output is uvm_do_with 4 and 6 values only.


start() nayana topicss


do method sukeerthana topics



Piyush topics

Macros for pre-existing items

These macros are used to start sequences and sequence items that do not need to be created.
If we already have a data object that we simply want to send to the sequencer, we can use `uvm_send. There are different variations to this macro

  1. `uvm_send
  2. `uvm_send_pri  
  3. `uvm_rand_send
  4. `uvm_rand_send_pri
  5. `uvm_rand_send_with  
  6. `uvm_rand_send_pri_with

1. `uvm send:

This macro processes the item or sequence that has been created using `uvm_create.
The processing is done without randomization. Essentially, an uvm_do without the create or randomization. It directly sends a seq/item without creating and randomizing it. So, make sure the seq/item is created and randomized first. In this ,create() and randomize() are skipped.

  • Syntax:

          uvm_send(SEQ_OR_ITEM)
    
  • 2. `uvm_send_pri:

It is the same as `uvm_send but additionally, priority is also considered.This is the same as uvm_send except that the sequence item or sequence is executed with the priority specified in the argument. In this, create() and randomize() are skipped and priority is also considered.

  • Syntax:

          `uvm_send_pri(SEQ_OR_ITEM, PRIORITY)
    

3. `uvm_rand_send:

This macro processes the item or sequence that has been already been allocated (possibly with `uvm_create). The processing is done with randomization. Essentially, an uvm_do without the create. It directly sends a randomized seq/item without creating it. So, make sure the seq/item is created first.

  • Syntax:

          `uvm_rand_send(SEQ_OR_ITEM)
    

4. `uvm_rand_send_pri:

This is the same as `uvm_rand_send except that the sequence item or sequence is executed with the priority specified in the argument. It is combination of uvm_rand_send and uvm_send_pri. In this Only create() is skipped, the rest all other steps are executed with the priority mentioned.

  • Syntax:

           `uvm_rand_send_pri(SEQ_OR_ITEM, PRIORITY)
    

5. `uvm_rand_send_with:

This is the same as `uvm_rand_send except that the given constraint block is applied to the item or sequence in a randomize with a statement before execution. It directly sends a randomized seq/item with constraints but without creating it. So, make sure the seq/item is created first. create() is skipped, rest of the other steps are executed along with constraints defined in the second argument.

  • Syntax:

            `uvm_rand_send_with(SEQ_OR_ITEM, CONSTRAINTS)
    

6. `uvm_rand_send_pri_with:

This is the same as `uvm_rand_send_pri except that the given constraint block is applied to the item or sequence in a randomize with the statement before execution. It is a combination of uvm_rand_send_with and uvm_send_pri. create() is skipped, rest of the other steps are executed along with constraints defined with the priority mentioned.

  • Syntax:

         `uvm_rand_send_pri_with(SEQ_OR_ITEM, PRIORITY, CONSTRAINTS)
    

Code Snippet:

                    class sequence1 extends uvm_sequence#(transaction);
                   `uvm_object_utils(sequence1)

                    function new(input string name="sequence1");
                    super.new(name);
                    endfunction
                    transaction trans1;
                    transaction trans2;
                    //transaction trans3;

                     virtual task body();
                     `uvm_create(trans1)   // create the trans1 object

                     `uvm_info("Trans1","Trans1 is created",UVM_NONE);
                     void'(trans1.randomize());
                     `uvm_info("Trans1","Trans1 is randomize",UVM_NONE);
                     `uvm_send(trans1) // sending the trans1
                     trans1.print();
                     `uvm_info("Trans1", "Create , Randomization and send all done for trans1 ",UVM_NONE);

                     `uvm_create(trans2)
                     `uvm_info("Trans2","Trans2 is created",UVM_NONE)
                     `uvm_rand_send(trans2)   // Randomization and send of data in one step
                     `uvm_info("Trans","Trans2 is randomize and the send data",UVM_NONE)
                     trans2.print();
                     `uvm_info("Trans2","using with ",UVM_NONE)
                     `uvm_rand_send_with(trans2,{trans2.a==2;
                      trans2.b==4;})    // using inline constraint
                      trans2.print();
                     `uvm_info("Trans2","Create , randomization and send is done for trans2",UVM_NONE)

                     endtask
                     endclass

Output Snap:

tt drawio


Naveen task

SEQUENCE LIBRARY :

UVM provides a class for randomly creating and running sequences. This class is called uvm_sequence_library. The uvm_sequence_library class is generally inherited from uvm_sequence, from this we can know that sequence library is also similar to a sequence. We can define multiple derived test sequences in a program and this is merged into a single test sequence which increases the random nature of execution. Such merging can be achieved by using uvm_sequence_library.

sequence_library

           Figure 1. Above figure shows the merging of many  sequences into a single sequence.   

The uvm_sequence_library also provides control to user in terms of sequence selection logic and which sequences to be executed prior to any other sequences. You can ever order the sequence items and can even remove the irrelevant sequence items.

sequence library hierarchy

           Figure 2. sequence library heirarchy.   

1. Sequence Registration Inside Sequence Library :

Sequences can be registered with a sequence library either by using a macro or function calls. To register a sequence(s) with every instance of a particular type of sequence library, the add_typewide_sequence() is used.
Code snippets for multiple uvm components and objects are shown below.

1. Calling “add_typewide_sequence” from sequence library:

   class my_seq_lib extends uvm_sequence_library #(my_packet);
       . . .
       function new(string name = "my_seq_lib");
       . . .
          add_typewide_sequence(my_seq::get_type());
          add_typewide_sequence(my_seq2::get_type());
       endfunction
      . . .
    endclass: my_seq_lib

2. Calling “add_sequence” from testcase:

       class my_test extends uvm_test;
        . . .

             virtual function void build_phase(uvm_phase phase);
              . . .
                   seq_lib.add_sequence(my_seq::get_type());
                   seq_lib.add_sequence(my_seq2::get_type());
              endfunction: build_phase
          . . .
        endclass  

3. Calling “uvm_add_to_seq_lib” from testcase:

            class my_test extends uvm_test;

           `uvm_add_to_seq_lib(my_seq, my_seq_lib)
          `uvm_add_to_seq_lib(my_seq2, my_seq_lib)
           . . .
            
           endclass    

4. Calling “add_typewide_sequences” from sequence library:

               class my_seq_lib extends uvm_sequence_library #(my_packet);
                . . .
                    function new(string name = "my_seq_lib");
                     . . .
                        add_typewide_sequences({my_seq::get_type(),
                         my_seq2::get_type()});
                     endfunction
                 . . .
                 endclass: my_seq_lib  

5. Calling “add_sequences’ from testcase:

                      class my_test extends uvm_test;
                         . . .

                          virtual function void build_phase(uvm_phase phase);
                             . . .
                             seq_lib.add_sequences({my_seq::get_type(),
                             my_seq2::get_type()});
                          endfunction: build_phase
                         . . .
                      endclass    

2. Sequence Library Controls :

Library behavior is controlled by properties.

  1. min_random_count : Lower constraint for random number (default 10).
  2. max_random_count : Upper constraint for random number (default 10).

Selection mode:

  • Syntax : uvm_sequence_lib_mode selection_mode It specifies the mode or the order in which the sequences to be executed and the selection of the sequence can be customized by the user using 4 variations. They are,
Enum Value Description
UVM_SEQ_LIB_RAND Random sequence selection (Default selection_mode).
UVM_SEQ_LIB_RANDC Random cyclic sequence selection
UVM_SEQ_LIB_ITEM Emit only items, no sequence execution
UVM_SEQ_LIB_USER Apply a user-defined random-selection algorithm
  1. Select rand : The index variable that is randomized to select the next sequence to execute when in UVM_SEQ_LIB_RAND mode.
  2. Select randc : The index variable that is randomized to select the next sequence to execute when in UVM_SEQ_LIB_RANDC mode.
  3. Select item : Generates data items only, no sequence is executed by using UVM_SEQ_LIB_ITEM mode.
  4. select sequence : Generates an index used to select the next sequence to execute. Overrides must return a value between 0 and max, inclusive. Used only for UVM_SEQ_LIB_USER selection mode.

Sequence Registration :

All classes of sequences are derived directly from uvm_sequence (as shown in figure 2) and those sequences are merged into a single sequence using uvm_sequence_library. This sequence_library has to be registered with the factory using uvm-sequence_library_utils macro.

This class must be instantiated and also need to create constructor while using in the other classes. We also need to call init_sequence_library in the constructor in order to setup and construct the library infrastructure. Init library cannot have a task body, cannot define its own sequence but it can only have predefined sequences into the library.

  • Example :

                 class environment extends uvm_env;
    
                        `uvm_component_utils(environment)
                          agent a;
                      function new(string name="environment",uvm_component parent=null);
                           super.new(name,parent);
                     endfunction
    
                      virtual function void build_phase(uvm_phase phase);
                          super.build_phase(phase);
                          a=agent::type_id::create("a",this);
                      endfunction
    
                 endclass
    
                 class test extends uvm_test;
                    `uvm_component_utils(test)
                      my_seq_lib seq_lib;
                      sequence1 s1;
                      sequence2 s2;
                      environment env;
    
                      function new(string name="test",uvm_component parent=null);
                           super.new(name,parent);
                       endfunction
    
                      virtual function void build_phase(uvm_phase phase);
                              super.build_phase(phase);
                              env = environment::type_id::create("env",this);
                              seq_lib=my_seq_lib::type_id::create("seq_lib");
                              s1=sequence1::type_id::create("s1");
                              s2=sequence2::type_id::create("s2");
                       endfunction
    
                        virtual task run_phase(uvm_phase phase);
                                 phase.raise_objection(this);
                                 s1.start(env.a.seqr);
                                 s2.start(env.a.seqr);
                                 phase.drop_objection(this);
                            endtask
    
                      virtual task configure_phase(uvm_phase phase);
                                 super.configure_phase(phase);
                                 `uvm_info("config","add seq to lib",UVM_MEDIUM);
                                 seq_lib.selection_mode=UVM_SEQ_LIB_RANDC;
                                 seq_lib.min_random_count=1;
                                 seq_lib.max_random_count=3;
    
                                 seq_lib.add_typewide_sequence(s1.get_type());
                                 seq_lib.add_typewide_sequence(s2.get_type());
                                 seq_lib.init_sequence_library();
                          endtask
    
                  function void start_of_simulation_phase(uvm_phase phase);
                        super.start_of_simulation_phase(phase);
                        uvm_config_db#(uvm_sequence_base)::set(this,"env.a.seqr.main_phase","default_sequence",seq_lib);
                  endfunction
              endclass
    
            module tb;
              initial begin
                  run_test("test");
               end
            endmodule
    

In the above example, we extended sequence1 and sequence 2 from the uvm_sequence and for that we created a factory in the method by using the create method. Also we extend the class name by my_seq_lib by using UVM inbuild library uvm_sequence_library and after that initializing the Factory registration Macro. Then declaring the constructor method. seq_lib,s1 and s2 are the handles of the sequence library and seq classes. By using the following syntax, created the Factory method handle_name= class_name::type_id::create("handle_name");

Library behavior is controlled by properties that is min_random_count and max_random_count and it generates a random number between that range. For the selection of sequences from the library we have selection modes. In this example we used randc as a selection mode and we used init_sequence_library to include the sequences into our sequence_library which is my_seq_lib in our example.

  • Output Snap : uvm_seq_lib

          Output 1. Output of different sequences obtained after merging them into a single sequence library.   
    

uvm_seq_lib_report

                                       Output 2. Output for uvm report.